# 题目: 260. 只出现一次的数字 III
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
# 示例1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
# 示例2:
输入:nums = [-1,0]
输出:[-1,0]
# 题解1: 哈希
我们可以进行一次遍历,并使用哈希将元素出现的次数记录下来,最后在遍历哈希找到只出现过一次的元素。
# 代码
/**
* @param {number[]} nums
* @return {number[]}
*/
var singleNumber = function(nums) {
let map = new Map()
let res = []
for(let i of nums){
map.set(i,(map.get(i) || 0) + 1)
}
for(let [key,value] of map){
if(value === 1) res.push(key)
}
return res
};
# 题解2: 位运算
根据异或运算,相同为0,不同为1,我们可以将所有的元素进行异或,则可以得到:
x_1,x_2为数组中不同的两个元素。
下一步的我们需要从得到x拿到x_1,x_2。
借助 $x \oplus -x $ 取出 x 二进制表达式中最低位的那个1,设其为第l位,那么x_1和x_2在第l位一定一个是1,一个是0。
我们通过这一位将nums中的元素,分为两类,即一类是第l位为1,一类第l位为0。而x_1,x_2肯定在不同类的,而其余重复的两个元素一定会被分到同一类中。这样,我们就将nums分成了两个数组,每个数组包含了一个不重复的元素,在这个数组中,我们再次异或就可以得到答案。
# 代码
var singleNumber = function(nums) {
let xorsum = 0;
for (const num of nums) {
xorsum ^= num;
}
let type1 = 0, type2 = 0;
const lsb = xorsum & (-xorsum);
for (const num of nums) {
// 分类的同时,进行异或
if (num & lsb) {
type1 ^= num;
} else {
type2 ^= num;
}
}
return [type1, type2];
};